/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package uy.edu.ort.uruguayviajes.dao.servicios.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import uy.edu.ort.comun.dominio.dto.PaqueteDTO;
import uy.edu.ort.comun.dominio.dto.ReservaDTO;
import uy.edu.ort.comun.dominio.dto.UsuarioDTO;
import uy.edu.ort.uruguayviajes.dao.entities.PaqueteTuristico;
import uy.edu.ort.uruguayviajes.dao.entities.Reserva;
import uy.edu.ort.uruguayviajes.dao.entities.Usuario;
import uy.edu.ort.uruguayviajes.dao.excepcion.DaoException;
import uy.edu.ort.uruguayviajes.dao.servicios.DaoServices;

/**
 *
 * @author dberriel
 */
@Stateless
public class DaoServicesBean implements DaoServices {
    
    @PersistenceContext
    private EntityManager em;

    /**
     * Ingresa una reserva para un usuario
     * @param usuario
     * @param paquete
     * @param resultado 
     */
    public void ingresarReserva(UsuarioDTO usuario, PaqueteDTO paqueteDto, String autorizacion, String tarjeta) throws DaoException{
        try {
            Usuario usu = this.obtenerUsuario(usuario.getUsuario());
            Reserva reserva = new Reserva();
            reserva.setCodigoAutorizacion(autorizacion);
            PaqueteTuristico paquete = new PaqueteTuristico();
            paquete.setCodigo(paqueteDto.getCodigo());
            paquete.setCosto(paqueteDto.getCosto());
            paquete.setDescripcion(paqueteDto.getDescripcion());
            paquete.setDestino(paqueteDto.getDestino());
            paquete.setFechaLlegada(paqueteDto.getFechaLlegada());
            paquete.setFechaSalida(paqueteDto.getFechaSalida());
            paquete.setMoneda(paquete.getMoneda());
            paquete.setOrigen(paqueteDto.getOrigen());
            paquete.setServicios(paqueteDto.getServicios());
            reserva.setTarjeta(tarjeta);
            em.persist(paquete);
            reserva.setPaquete(paquete);
            em.persist(reserva);
            usu.agregarReserva(reserva);
            em.persist(usu);
        }
        catch(Exception ex){
            throw new DaoException("No se pudo ingresar la reserva.");
        }
    }

    /**
     * Obtiene la lista de reservas de un usuario
     * @param usuario
     * @return 
     */
    public List<ReservaDTO> obtenerReservas(UsuarioDTO usuario) throws DaoException{
        try{    
            Usuario u = this.obtenerUsuario(usuario.getUsuario());
            //ver si es lazy
            List<Reserva> reservas = u.getListaReservas();
            return reservasToDto(reservas);
        }
        catch(Exception ex){
            throw new DaoException("No se pudo obtener las reservas.");
        }
    }
    
    private List<ReservaDTO> reservasToDto(List<Reserva> reservas) throws DaoException {
        try{    
            Iterator it = reservas.iterator();
            List<ReservaDTO> reservasDTO = new ArrayList<ReservaDTO>();
            while (it.hasNext()) {
                Reserva r = (Reserva) it.next();
                ReservaDTO resDto = new ReservaDTO();
                resDto.setCodigoAutorizacion(r.getCodigoAutorizacion());
                resDto.setEstado(r.getEstado());
                resDto.setTarjeta(r.getTarjeta());
                //obtengo el paquete de la reserva
                PaqueteTuristico p = r.getPaquete();
                PaqueteDTO paqDto = new PaqueteDTO();
                paqDto.setCodigo(p.getCodigo());
                paqDto.setCosto(p.getCosto());
                paqDto.setDescripcion(p.getDescripcion());
                paqDto.setDestino(p.getDestino());
                paqDto.setFechaLlegada(p.getFechaLlegada());
                paqDto.setFechaSalida(p.getFechaSalida());
                paqDto.setMoneda(p.getMoneda());
                paqDto.setOrigen(p.getOrigen());
                paqDto.setServicios(p.getServicios());
                resDto.setPaquete(paqDto);
                reservasDTO.add(resDto);
            }
            return reservasDTO;
        }
        catch(Exception ex){
            throw new DaoException("No se pudo obtener las reserva.");
        }
    }
    
    private List<UsuarioDTO> usuariosToDto(List<Usuario> usuarios) throws DaoException {
        try{
            Iterator it = usuarios.iterator();
            List<UsuarioDTO> usuariosDTO = new ArrayList<UsuarioDTO>();
            while (it.hasNext()) {
                Usuario u = (Usuario) it.next();
                UsuarioDTO uDto = convertirUsuarioADTO(u);
                usuariosDTO.add(uDto);
            }
            return usuariosDTO;
            }
        catch(Exception ex){
            throw new DaoException("No se pudo obtener los usuarios.");
        }
    }
    
    private UsuarioDTO convertirUsuarioADTO(Usuario u) throws DaoException{
        try{
            UsuarioDTO uDto = new UsuarioDTO();
            uDto.setNombres(u.getNombres());
            uDto.setApellidos(u.getApellidos());
            uDto.setCiudad(u.getCiudad());
            uDto.setCodigoPostal(u.getCodigoPostal());
            uDto.setDireccion(u.getDireccion());
            uDto.setEmail(u.getEmail());
            uDto.setListaReservas(reservasToDto(u.getListaReservas()));
            uDto.setPassword(u.getPassword());
            uDto.setSexo(u.getSexo());
            uDto.setTelefono(u.getTelefono());
            uDto.setUsuario(u.getUsuario());
            uDto.setfNacimiento(u.getfNacimiento());
            return uDto;
            }
        catch(Exception ex){
            throw new DaoException("No se pudo obtener el usuario.");
        }
    }

    /**
     * obtiene un usuario
     * @param nomUsuario
     * @return 
     */
    public Usuario obtenerUsuario(String login) throws DaoException{
        try{
            String querystr = "select u from Usuario u where u.usuario = :pUsuario";
            List<Usuario> usuarios = em.createQuery(querystr).setParameter("pUsuario", login).getResultList();
            return usuarios.get(0);
            }
        catch(Exception ex){
            throw new DaoException("No se pudo obtener el usuario.");
        }
    }

    /**
     * obtiene un usuarioDTO
     * @param login
     * @return 
     */
    public UsuarioDTO obtenerUsuarioDTO(String login) throws DaoException{
        try{
            Usuario u = this.obtenerUsuario(login);
            UsuarioDTO usuario = convertirUsuarioADTO(u);
            return usuario;
            }
        catch(Exception ex){
            throw new DaoException("No se pudo ingresar la reserva.");
        }
    }

    /**
     * Ingresa un usuario
     * @param nombres
     * @param apellidos
     * @param sexo
     * @param fNacimiento
     * @param direccion
     * @param telefono
     * @param codigoPostal
     * @param ciudad
     * @param email
     * @param usuario
     * @param password 
     */
    public void ingresarUsuario(String nombres, String apellidos, String sexo, Date fNacimiento,
            String direccion, String telefono, String codigoPostal, String ciudad, String email, String login, String password) throws DaoException {
        try{
            Usuario usuario = new Usuario();
            usuario.setNombres(nombres);
            usuario.setApellidos(apellidos);
            usuario.setSexo(sexo);
            usuario.setfNacimiento(fNacimiento);
            usuario.setDireccion(direccion);
            usuario.setTelefono(telefono);
            usuario.setCiudad(ciudad);
            usuario.setCodigoPostal(codigoPostal);
            usuario.setEmail(email);
            usuario.setUsuario(login);
            usuario.setPassword(password);
            em.persist(usuario);
            }
        catch(Exception ex){
            throw new DaoException("No se pudo ingresar el usuario.");
        }
    }
    
    public boolean validarUsuario(String login, String password) throws DaoException{
        try{
            boolean result = Boolean.FALSE;

            Usuario usuario = this.obtenerUsuario(login);
            if (usuario != null && usuario.getPassword().equalsIgnoreCase(password)) {
                result = Boolean.TRUE;
            }
            return result;
            }
        catch(Exception ex){
            throw new DaoException("No se pudo ingresar la reserva.");
        }
    }
    
    public void actualizarReserva(String codAutorizacion, String estado)throws DaoException{
        try{
            Reserva reserva = this.obtenerReserva(codAutorizacion);
            reserva.setEstado(estado);
            em.persist(reserva);
            }
        catch(Exception ex){
            throw new DaoException("No se pudo ingresar la reserva.");
        }
    }
    
    private Reserva obtenerReserva(String codAutorizacion)throws DaoException{
        try{
            String querystr = "select u from Reserva r where r.codigoAutorizacion = :pReserva";
            List<Reserva> reservas = em.createQuery(querystr).setParameter("pReserva", codAutorizacion).getResultList();
            return reservas.get(0);
            }
        catch(Exception ex){
            throw new DaoException("No se pudo ingresar la reserva.");
        }
    }
}
